#include "sysfilepathsmodel.h"
#include "cgproto.pb.h"
#include "client-socket.h"
#include "commonfunc.h"
#include <QUrlQuery>
#include <QNetworkReply>

CNS_SYS_REGISTER(SysFilePathsModel);

SysFilePathsModel::SysFilePathsModel()
{

}

QStandardItem* findStandardItemChild(QStandardItem* item, const QString &text)
{
    for(int i=0; i < item->rowCount(); i ++)
    {
        QStandardItem* it = item->child(i);
        if(it->text() == text)
        {
            return it;
        }
    }
    return nullptr;
}

void insertModelItemItem(int index, QStandardItem* item, const QStringList &paths, const QString &files)
{
    if(index < paths.size()){
        const QString &text = paths[index];
        QStandardItem* child = findStandardItemChild(item, text);
        if(child) return;
        child = new QStandardItem(text);
        item->appendRow(child);
        insertModelItemItem(index+1, child, paths, files);
    }
    else{
        QStringList sl = files.split(';');
        for(QStringList::iterator it = sl.begin(); it != sl.end(); it++)
        {
            QStandardItem* child = findStandardItemChild(item, *it);
            if(child) continue;
            child = new QStandardItem(*it);
            item->appendRow(child);
        }
    }
}


void insertModelItem(int index, CnsStandardItemModelPtr model, const QStringList &paths, const QString &files)
{
    if(index < paths.size()){
        const QList<QStandardItem*> &items = model->findItems(paths[index]);
        QStandardItem* item;
        if(items.empty())
        {
            item =new QStandardItem(paths[index]);
            model->appendRow(item);
        } else{
            item = items[0];
        }
        insertModelItemItem(index+1, item, paths, files);
    }
    else{
        QStringList sl = files.split(';');
        for(QStringList::iterator it = sl.begin(); it != sl.end(); it++)
        {
            const QList<QStandardItem*> &items = model->findItems(*it);
            if(items.isEmpty()){
                QStandardItem* item = new QStandardItem(*it);
                model->appendRow(item);
            }
        }
    }
}

void SysFilePathsModel::f__on_read(CnsComponentPtr com, cgproto::Message& msg)
{
    cgproto::FilePathsNotice fpNotice;
    ClientSocketProc *client = CAST_REF_TYPE_FROM_VOID(ClientSocketProc, com.data());
    if(client->getBaseProto().decode(msg.body().c_str(), static_cast<int>(msg.body().size()), fpNotice))
    {
        CnsStandardItemModelPtr model = com->propertyInNs("model").value<CnsStandardItemModelPtr>();
        for(int i =0; i < fpNotice.filepaths_size(); i ++)
        {
            const cgproto::FilePathsNotice::PathFiles &pf = fpNotice.filepaths(i);
            CNSLOG_DEBUG(QString("path info is %1 has %2!").arg(pf.path().c_str()).arg(pf.files().c_str()));
            QStringList paths = QString(pf.path().c_str()).split('/', QString::SkipEmptyParts);
            insertModelItem(0, model, paths, pf.files().c_str());
        }
    }
}

void SysFilePathsModel::f_start(CnsComponentPtr com)
{
    CnsStandardItemModelPtr model = com->propertyInNs("model").value<CnsStandardItemModelPtr>();
    model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("files"));
}

void SysFilePathsModel::f_itemClicked(CnsComponentPtr com, const QModelIndex &index)
{
    CnsStandardItemModelPtr model = com->propertyInNs("model").value<CnsStandardItemModelPtr>();
    QStringList paths;
    QModelIndex idx = index;
    while(idx.isValid())
    {
        paths.push_front(model->data(idx).toString());
        idx = idx.parent();
    }
    QString path = paths.join('/');

    QUrl url("http://127.0.0.1:8080/"+path);
    QUrlQuery query;

    url.setQuery(query);

    CnsNetworkAccessManagerPtr network = com->property("networkAccessManager").value<CnsNetworkAccessManagerPtr>();

    QNetworkReply *rep = network->get(QNetworkRequest(url));
    connect(rep, &QNetworkReply::finished,
            this, [rep, com]() {
        com->exec("handleGnFileData", Q_ARG(QNetworkReply *, rep));
    });

}

